package com.example.lightcamera

import android.Manifest
import android.os.Bundle
import android.view.SurfaceView
import android.view.TextureView
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import android.widget.LinearLayout
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.media3.exoplayer.rtsp.RtspMediaSource
import androidx.media3.datasource.DefaultDataSource
import androidx.media3.datasource.DefaultDataSource.Factory
import com.pedro.library.rtsp.RtspCamera1
import com.pedro.common.ConnectChecker
import androidx.media3.common.MediaItem
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.ui.PlayerView
import android.widget.FrameLayout
import android.widget.TextView
import android.widget.ScrollView
import android.view.Gravity
import android.view.View
import android.view.MotionEvent

class MainActivity : AppCompatActivity(), SignalingClient.Listener {

  private lateinit var surfaceView: SurfaceView
  private lateinit var rtspCamera1: RtspCamera1
  private lateinit var etUrl: EditText
  private lateinit var btnStartStop: Button
  private lateinit var btnSwitch: Button
  private lateinit var player: ExoPlayer
  private lateinit var playerView: PlayerView
  private lateinit var controlsLayout: LinearLayout
  private lateinit var tvLogs: TextView
  private lateinit var debugPanel: ScrollView
  
  private lateinit var myRoomId: String
  private lateinit var signaling: SignalingClient
  private var isCameraFull = true  // 摄像头是否全屏

  private val requestPermissions = registerForActivityResult(
    ActivityResultContracts.RequestMultiplePermissions()
  ) { result ->
    val cam = result[Manifest.permission.CAMERA] == true
    val mic = result[Manifest.permission.RECORD_AUDIO] == true
    if (cam && mic) {
      initCameraAndPreview()
    } else {
      Toast.makeText(this, "需要相机和麦克风权限", Toast.LENGTH_SHORT).show()
      finish()  // 权限没给，直接关闭 Activity
    }
  }

  override fun onRoomCreated(roomId: String) {
    runOnUiThread {
      if (!rtspCamera1.isStreaming) {
        
        myRoomId = roomId
        val url = "rtsp://192.168.1.5:8554/$roomId?tcp"
        // 先准备编码器
        if (rtspCamera1.prepareAudio() && rtspCamera1.prepareVideo()) {
          // 向这个房间号推流
          rtspCamera1.startStream(url)
        } else {
          toast("编码器准备失败")
        }
      } else {
        rtspCamera1.stopStream()
      }
    }
  }
  override fun onConnectRoom(roomId: String) {
    runOnUiThread {
      // 有人加入了我的房间,那我拉他房间的流
      val url = "rtsp://192.168.1.5:8554/$roomId?tcp"
      val mediaItem = MediaItem.fromUri(url)
      player.setMediaItem(mediaItem)
      player.prepare()
      player.playWhenReady = true

      etUrl.visibility = View.GONE
      btnStartStop.text = "退出房间"
    }
  }

  override fun onJoinedRoom(roomId: String) {
    runOnUiThread {
      Toast.makeText(this, "加入房间: $roomId", Toast.LENGTH_LONG).show()
    }
  }

  override fun onMessage(from: String, message: String) {
    
  }

  override fun onError(error: String) {

  }

  private fun initCameraAndPreview() {
    
    // 初始化 RTSP 推流
    rtspCamera1 = RtspCamera1(surfaceView, object : ConnectChecker {

      override fun onConnectionStarted(url: String) {
        runOnUiThread { toast("RTSP 开始连接") }
      }
      override fun onConnectionSuccess() {
        runOnUiThread { toast("RTSP 连接成功") }
      }
      override fun onConnectionFailed(reason: String) {
        runOnUiThread {
          toast("RTSP 连接失败：$reason")
          if (rtspCamera1.isStreaming) rtspCamera1.stopStream()
        }
      }
      override fun onNewBitrate(bitrate: Long) {}
      override fun onDisconnect() {
        runOnUiThread { toast("RTSP 已断开") }
      }
      override fun onAuthError() {
        runOnUiThread { toast("RTSP 认证失败") }
      }
      override fun onAuthSuccess() {
        runOnUiThread { toast("RTSP 认证成功") }
      }
    })

    // 加入房间
    btnStartStop.setOnClickListener {

      // 这里是房间号
      val roomNumber = etUrl.text.toString().trim()
      if (roomNumber.isEmpty()) {
        toast("请填写房间号")
        return@setOnClickListener
      }
      val url = "rtsp://192.168.1.5:8554/$roomNumber?tcp"

      // val dataSourceFactory = DefaultDataSource.Factory(this)
      // val rtspFactory = RtspMediaSource.Factory()
      // rtspFactory.setForceUseRtpTcp(true)  // 强制使用 TCP
      // val mediaItem = MediaItem.fromUri(url)
      // val mediaSource = rtspFactory.createMediaSource(mediaItem)

      // player.setMediaSource(mediaSource)
      // player.prepare()
      // player.playWhenReady = true

      signaling.joinRoom(roomNumber, myRoomId)

      // 播放拉流
      val mediaItem = MediaItem.fromUri(url)
      player.setMediaItem(mediaItem)
      player.prepare()
      player.playWhenReady = true

      etUrl.visibility = View.GONE
      btnStartStop.text = "退出房间"
    }

    // 切换前后摄像头
    btnSwitch.setOnClickListener {
      try {
        rtspCamera1.switchCamera()
      } catch (e: Exception) {
        toast("切换摄像头失败：${e.message}")
      }
    }

    // 点击任意一个画面切换大小
    val switchViews: () -> Unit = {
      val camParams = surfaceView.layoutParams as FrameLayout.LayoutParams
      val rtspParams = playerView.layoutParams as FrameLayout.LayoutParams

      if (isCameraFull) {
        // 摄像头变小窗
        camParams.width = dp2px(150)
        camParams.height = dp2px(200)
        camParams.gravity = Gravity.TOP or Gravity.END
        camParams.marginEnd = dp2px(16)
        camParams.bottomMargin = dp2px(16)
        surfaceView.layoutParams = camParams
        surfaceView.setZOrderMediaOverlay(true)
        surfaceView.bringToFront()

        // 拉流全屏
        rtspParams.width = FrameLayout.LayoutParams.MATCH_PARENT
        rtspParams.height = FrameLayout.LayoutParams.MATCH_PARENT
        rtspParams.gravity = Gravity.CENTER
        rtspParams.marginEnd = 0
        rtspParams.bottomMargin = 0
        playerView.layoutParams = rtspParams

        // 摄像头小窗
        // enableDrag(surfaceView)
      } else {
        // 摄像头全屏
        camParams.width = FrameLayout.LayoutParams.MATCH_PARENT
        camParams.height = FrameLayout.LayoutParams.MATCH_PARENT
        camParams.gravity = Gravity.CENTER
        camParams.marginEnd = 0
        camParams.bottomMargin = 0
        surfaceView.layoutParams = camParams
        surfaceView.setZOrderMediaOverlay(false)

        // 拉流小窗
        rtspParams.width = dp2px(150)
        rtspParams.height = dp2px(200)
        rtspParams.gravity = Gravity.TOP or Gravity.END
        rtspParams.marginEnd = dp2px(16)
        rtspParams.bottomMargin = dp2px(16)
        playerView.layoutParams = rtspParams
        playerView.bringToFront()

        // 拉流小窗
        // enableDrag(playerView)
      }

      // 控件永远在最上层
      controlsLayout.bringToFront()
      isCameraFull = !isCameraFull
    }
    
    surfaceView.setOnClickListener { switchViews() }
    playerView.setOnClickListener { switchViews() }

    // 显示当前摄像头缓慢
    if (!rtspCamera1.isOnPreview) {
      // 可根据需求设置分辨率、帧率、码率（也可以用 prepareVideo(width, height, fps, bitrate, iFrameInterval)）
      rtspCamera1.startPreview()
    }

    // 向信令服务器注册
    val wsUrl = "ws://192.168.1.5:8080/ws"
    signaling = SignalingClient(wsUrl, this, tvLogs)
    signaling.connect()
  }

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    controlsLayout = findViewById(R.id.controlsLayout)
    surfaceView = findViewById(R.id.surfaceView)
    etUrl = findViewById(R.id.etUrl)
    btnStartStop = findViewById(R.id.btnStartStop)
    btnSwitch = findViewById(R.id.btnSwitch)
    playerView = findViewById(R.id.playerView)
    tvLogs = findViewById(R.id.tvDebugLogs)
    debugPanel = findViewById(R.id.debugScrollView)
    player = ExoPlayer.Builder(this).build()
    playerView.player = player

    // 开发阶段显示日志
    // debugPanel.visibility = View.VISIBLE

    // 正式发布时隐藏
    debugPanel.visibility = View.GONE

    // 申请权限
    requestPermissions.launch(arrayOf(
      Manifest.permission.CAMERA,
      Manifest.permission.RECORD_AUDIO
    ))
  }
  
  override fun onStop() {
    super.onStop()
    // 进入后台时仅停止预览，保留状态
    if (rtspCamera1.isOnPreview && !rtspCamera1.isStreaming) {
      // rtspCamera1.stopPreview()
    }
  }

  override fun onDestroy() {
    super.onDestroy()
    if (rtspCamera1.isStreaming) rtspCamera1.stopStream()
    rtspCamera1.stopPreview()
    player.release()
  }

  private fun toast(msg: String) =
    Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()

  private fun dp2px(dp: Int): Int {
    val scale = resources.displayMetrics.density
    return (dp * scale + 0.5f).toInt()
  }

  private fun enableDrag(view: View) {
    var dX = 0f
    var dY = 0f

    view.setOnTouchListener { v, event ->
      // 仅在小窗模式才允许拖动
      if (isCameraFull && view == surfaceView) return@setOnTouchListener false
      if (!isCameraFull && view == playerView) return@setOnTouchListener false

      when (event.action) {
        MotionEvent.ACTION_DOWN -> {
            dX = v.x - event.rawX
            dY = v.y - event.rawY
        }
        MotionEvent.ACTION_MOVE -> {
            // 限制拖动范围在父布局内
            val parent = v.parent as View
            val newX = (event.rawX + dX).coerceIn(0f, parent.width - v.width.toFloat())
            val newY = (event.rawY + dY).coerceIn(0f, parent.height - v.height.toFloat())
            v.animate().x(newX).y(newY).setDuration(0).start()
          }
      }
      true
    }
  }
}
